﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Security;
using System.Web;

namespace HiLand.Utility.Web
{
    public static class LoginValidation
    {
        /// <summary>
        /// 为验证写入数据
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="roleList"></param>
        public static void Write(string userName, List<string> roleList)
        {
            string roles = string.Empty;
            if (roleList != null)
            {
                for (int i = 0; i < roleList.Count; i++)
                {
                    roles += string.Format("[role]:{0}", roleList[i]);
                }
            }

            FormsAuthenticationTicket authTicket = new
                            FormsAuthenticationTicket(1,                    // version
                                                userName,                   // user name
                                                DateTime.Now,               // creation
                                                DateTime.Now.AddMinutes(60),// Expiration
                                                false,                      // Persistent
                                                roles);
            string encryptedTicket = FormsAuthentication.Encrypt(authTicket);//Encrypt方法创建一个字符串，其中包含适用于 HTTP Cookie 的加密的 Forms 身份验证票证
            HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); //将加密的票据加入到Cookie中，
            //FormsAuthentication.FormsCookieName获取的就是配置文件中名为AuthCookie的Cookie
            HttpContext.Current.Response.Cookies.Add(authCookie); //加入到Cookie中，这一步很重要，加入后代表已携带身份
        }

        /// <summary>
        /// 为验证写入数据并且跳转到登录前的页面
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="roleList"></param>
        public static void WriteAndRedirect(string userName, List<string> roleList)
        {
            Write(userName, roleList);

            string originalUrl = HttpContext.Current.Request.QueryString["returnurl"];
            if (string.IsNullOrEmpty(originalUrl))
            {
                originalUrl = FormsAuthentication.DefaultUrl;
            }

            if (string.IsNullOrEmpty(originalUrl))
            {
                originalUrl = "~/";
            }

            HttpContext.Current.Response.Redirect(originalUrl);
        }


        public static bool Read(string virtualPathValidated, params string[] rolesValidated)
        {
            bool isSuccessfule = false;
            string currentVirtualPath = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.ToLower();
            virtualPathValidated = virtualPathValidated.ToLower();
            if (currentVirtualPath.StartsWith(virtualPathValidated) == false)
            {
                isSuccessfule = true;
                return isSuccessfule;
            }


            string cookieName = FormsAuthentication.FormsCookieName;
            HttpCookie authCookie = HttpContext.Current.Request.Cookies[cookieName];//获取web.config中的名为“AuthCookie”的Cookie值
            if (authCookie == null)
            {
                isSuccessfule = false;
                return isSuccessfule;
            }

            FormsAuthenticationTicket authTicket = null;
            try
            {
                //解密身份票据
                authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            if (authTicket == null)
            {
                // 如果没有则返回
                isSuccessfule = false;
                return isSuccessfule;
            }

            //如果有角色可以获取传递的用户数据
            //用户数据在登入代码中实例化FormsAuthenticationTicket时设置的。string userdata
            string[] roles = authTicket.UserData.Split(new string[] { "[role]:" }, StringSplitOptions.RemoveEmptyEntries);
            //创建标识对象
            System.Security.Principal.IIdentity id = new FormsIdentity(authTicket);
            //创建安全主体
            System.Security.Principal.IPrincipal principal = new System.Security.Principal.GenericPrincipal(id, roles);
            // 添加到Http上下文中
            HttpContext.Current.User = principal;


            if (virtualPathValidated.StartsWith("/"))
            {
                virtualPathValidated = "~" + virtualPathValidated;
            }
            if (virtualPathValidated.StartsWith("~/") == false)
            {
                virtualPathValidated = "~/" + virtualPathValidated;
            }

            if (currentVirtualPath.StartsWith(virtualPathValidated))
            {
                //需要验证是否登录
                if (rolesValidated != null)
                {
                    for (int i = 0; i < rolesValidated.Length; i++)
                    {
                        isSuccessfule = HttpContext.Current.User.IsInRole(rolesValidated[i]);
                        if (isSuccessfule == true)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                //不需要验证
                isSuccessfule = true;
            }

            return isSuccessfule;
        }

        public static void ReadAndRedirect(string virtualPathValidated, params string[] rolesValidated)
        {
            bool isSuccessfule = Read(virtualPathValidated, rolesValidated);
            if (isSuccessfule == false)
            {
                string targetUrl = FormsAuthentication.LoginUrl;

                if (string.IsNullOrEmpty(targetUrl))
                {
                    targetUrl = "~/login.aspx";
                }

                string currentVirtualPath = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.ToLower();
                if (string.IsNullOrEmpty(currentVirtualPath) == false)
                {
                    targetUrl += "?returnurl=" + currentVirtualPath;
                }
                HttpContext.Current.Response.Redirect(targetUrl);
            }
        }
    }
}
